home *** CD-ROM | disk | FTP | other *** search
/ Games of Daze / Infomagic - Games of Daze (Summer 1995) (Disc 1 of 2).iso / x2ftp / msdos / progsrc / 3d_2 / 3d_2a.h < prev    next >
Encoding:
C/C++ Source or Header  |  1994-12-18  |  9.5 KB  |  497 lines

  1. // version 1.03
  2.  
  3. //        sine angles use lookup table
  4. //        vectors are long integers
  5. //        surface now calculates normals for storage
  6.  
  7. // Header file for the program 3D_2a.CPP
  8. // 18/12/94
  9.  
  10. enum boolean {false, true};
  11. enum shading{none, hidden_line, lambert};
  12.  
  13. #include <graphics.h>
  14. #include <conio.h>
  15. #include <stdio.h>
  16. #include <string.h>
  17. #include <stdlib.h>
  18. #include <math.h>
  19. //#include <dos.h>
  20. #include <dir.h>
  21. #include <time.h>
  22. #include <iostream.h>         //  C++ i/o stream
  23. #include <fstream.h>
  24.  
  25.  
  26. float f_sin(int degree);
  27. float f_cos(int degree);
  28.  
  29. #define ANGLE 0.01745329
  30. #define YES 1
  31. #define NO 0
  32. #define MK_FP(seg,offset) \
  33.     ((void far *)(((unsigned long)(seg)<<16) | (unsigned)(offset)))
  34.  
  35.  
  36. // class for the vectors
  37. class vector
  38. {
  39.  private:
  40.    long x,y,z;
  41.  public:
  42.    friend vector operator+(vector op1, vector op2);
  43.    friend vector operator-(vector op1, vector op2);
  44.    friend vector operator-(vector op1, vector *op2);
  45.  
  46.    // multiply 2 vectors, dot-product
  47.    friend long dotproduct(vector op1, vector op2);
  48.    // find the normal of two vectors, or cross-product
  49.    friend vector normal(vector op1, vector op2);
  50.  
  51.    // multiply vector and float, result is a vector, scaling operation
  52.    friend vector operator*(float op1, vector op2);
  53.    vector operator=(vector op2);
  54.  
  55.    vector(void);
  56.  
  57.    long get_x(void)     {return x;};
  58.    long get_y(void)    {return y;};
  59.    long get_z(void)    {return z;};
  60.  
  61.    void assign(long mx, long my, long mz);
  62.    void assign(vector op1);
  63.    void assign(vector *op1);
  64. };
  65.  
  66. vector::vector(void)
  67. {
  68.  x = y = z = 0;
  69. }
  70.  
  71. vector operator+(vector op1, vector op2)
  72. {
  73.  vector temp;
  74.  
  75.  temp.x = op1.x + op2.x;
  76.  temp.y = op1.y + op2.y;
  77.  temp.z = op1.z + op2.z;
  78.  return temp;
  79. }
  80.  
  81. vector operator-(vector op1, vector op2)
  82. {
  83.  vector temp;
  84.  
  85.  temp.x = op1.x - op2.x;
  86.  temp.y = op1.y - op2.y;
  87.  temp.z = op1.z - op2.z;
  88.  return temp;
  89. }
  90.  
  91. vector operator-(vector op1, vector *op2)
  92. {
  93.  vector temp;
  94.  
  95.  temp.x = op1.x - op2 -> x;
  96.  temp.y = op1.y - op2 -> y;
  97.  temp.z = op1.z - op2 -> z;
  98.  return temp;
  99. }
  100.  
  101.  
  102. long dotproduct(vector op1, vector op2)
  103. {
  104.  long temp;
  105.  
  106.  temp = (op1.x * op2.x) + (op1.y * op2.y) + (op1.z * op2.z);
  107.  return temp;
  108. }
  109.  
  110. vector operator*(float op1, vector op2)
  111. {
  112.  vector temp;
  113.  
  114.  temp.x = op1 * op2.x;
  115.  temp.y = op1 * op2.y;
  116.  temp.z = op1 * op2.z;
  117.  return temp;
  118. }
  119.  
  120. vector vector::operator=(vector op2)
  121. {
  122.  x = op2.x;
  123.  y = op2.y;
  124.  z = op2.z;
  125.  return *this;
  126. }
  127.  
  128.  
  129. vector normal(vector op1, vector op2)
  130. {
  131.  vector temp;
  132.  
  133.  temp.x = op1.y*op2.z - op2.y*op1.z;
  134.  temp.y = op1.z*op2.x - op2.z*op1.x;
  135.  temp.z = op1.x*op2.y - op2.x*op1.y;
  136.  
  137.  return temp;
  138. }
  139.  
  140. void vector::assign(long mx, long my, long mz)
  141. {
  142.  x = mx;
  143.  y = my;
  144.  z = mz;
  145. }
  146.  
  147. void vector::assign(vector op1)
  148. {
  149.  x = op1.x;
  150.  y = op1.y;
  151.  z = op1.z;
  152. }
  153.  
  154. void vector::assign(vector *op1)
  155. {
  156.  x = op1 -> x;
  157.  y = op1 -> y;
  158.  z = op1 -> z;
  159. }
  160.  
  161.  
  162.  
  163.  
  164. class matrix
  165. {
  166. protected:
  167.   int rho, theta, phi;
  168.   float mat[3][4];
  169. public:
  170.   friend vector operator*(vector op1, matrix op2);
  171.   friend vector operator*(vector *op1, matrix op2);
  172.   friend void multiply(vector *op1, matrix op2);
  173.   friend void multiply(vector *op1, matrix *op2);
  174.  
  175.   matrix(void);               // constructor
  176.   ~matrix(void);                    // destructor
  177.   void set_rho(int r)        {rho += r;};
  178.   void set_theta(int t);
  179.   void set_phi(int p);
  180.   int get_rho(void)        {return rho;};
  181.   int get_theta(void)        {return theta;};
  182.   int get_phi(void)        {return phi;};
  183.   void calculate(void);
  184.   void set(float values[3][4]);
  185. };
  186.  
  187. matrix::matrix(void)
  188. {
  189.   for(register int i=0; i<3; i++)
  190.   {
  191.    for(register int j=0; j<4; j++)
  192.    {                                     //  matrix format
  193.     if (i==j)                         //        i
  194.      mat[i][j] = 1;                  //     0  1  2
  195.     else                                //   0 .  .  .
  196.      mat[i][j] = 0;                     //   1 .  .  .
  197.    }                                   // j 2 .  .  .
  198.   }                                     //   3 .  .  .
  199.  rho = 1700;
  200.  theta = 45;
  201.  phi = 60;
  202. }
  203.  
  204. void matrix::set_phi(int p)
  205. {
  206.  phi += p;
  207.  if (phi >= 360) phi -= 360;
  208.  if (phi < 0) phi += 360;
  209. }
  210.  
  211. void matrix::set_theta(int t)
  212. {
  213.  theta += t;
  214.  if (theta >= 360) theta -=360;
  215.  if (theta < 0) theta += 360;
  216. }
  217.  
  218. // load the matrix with the transformation data
  219. void matrix::set(float values[3][4])
  220. {
  221.  for(register int i=0; i<3; i++)
  222.   {
  223.    for(register int j=0; j<4; j++)
  224.    {
  225.     mat[i][j] = values[i][j];
  226.    }
  227.   }
  228. }
  229.  
  230. void matrix::calculate(void)
  231. {
  232.  float sin_theta, cos_theta, sin_phi, cos_phi;
  233.  
  234.  sin_theta = f_sin(theta);
  235.  cos_theta = f_cos(theta);
  236.  sin_phi = f_sin(phi);
  237.  cos_phi = f_cos(phi);
  238.  
  239.  mat[0][0] = -sin_theta;
  240.  mat[0][1] = cos_theta;
  241.  //mat[0][2] = 0;
  242.  //mat[0][3] = 0;
  243.  mat[1][0] = -(cos_theta * cos_phi);
  244.  mat[1][1] = -(sin_theta * cos_phi);
  245.  mat[1][2] = sin_phi;
  246.  //mat[1][3] = 0;
  247.  mat[2][0] = -(cos_theta * sin_phi);
  248.  mat[2][1] = -(sin_theta * sin_phi);
  249.  mat[2][2] = -cos_phi;
  250.  mat[2][3] = rho;
  251. }
  252.  
  253. // multiplies a vector with the matrix the result is
  254. // returned as a vector
  255. vector operator*(vector op1, matrix op2)
  256. {
  257.  long tmp[3];
  258.  long vec[4];
  259.  
  260.  for(register int i=0; i<3; i++)  tmp[i] = 0;
  261.  
  262.  vec[0] = op1.get_x();
  263.  vec[1] = op1.get_y();
  264.  vec[2] = op1.get_z();
  265.  vec[3] = 1.0;
  266.  
  267.  // multiply vector with transformation matrix
  268.  for(i=0; i<3; i++)
  269.  {
  270.   for(register int j=0; j<4; j++)
  271.   {
  272.    tmp[i] = tmp[i] + (vec[j] * op2.mat[i][j]);
  273.   }
  274.  }
  275.  
  276.  vector result;
  277.  result.assign(tmp[0], tmp[1], tmp[2]);
  278.  return result;
  279. }
  280.  
  281. vector operator*(vector *op1, matrix op2)
  282. {
  283.  long tmp[3];
  284.  long vec[4];
  285.  
  286.  for(register int i=0; i<3; i++)  tmp[i] = 0;
  287.  
  288.  vec[0] = op1 -> get_x();
  289.  vec[1] = op1 -> get_y();
  290.  vec[2] = op1 -> get_z();
  291.  vec[3] = 1.0;
  292.  
  293.  // multiply vector with transformation matrix
  294.  for(i=0; i<3; i++)
  295.  {
  296.   for(register int j=0; j<4; j++)
  297.   {
  298.    tmp[i] = tmp[i] + (vec[j] * op2.mat[i][j]);
  299.   }
  300.  }
  301.  
  302.  vector result;
  303.  result.assign(tmp[0], tmp[1], tmp[2]);
  304.  return result;
  305. }
  306.  
  307. void multiply(vector *op1, matrix op2)
  308. {
  309.  long tmp[3];
  310.  long vec[4];
  311.  
  312.  for(register int i=0; i<3; i++)  tmp[i] = 0;
  313.  
  314.  vec[0] = op1 -> get_x();
  315.  vec[1] = op1 -> get_y();
  316.  vec[2] = op1 -> get_z();
  317.  vec[3] = 1.0;
  318.  
  319.  // multiply vector with transformation matrix
  320.  for(i=0; i<3; i++)
  321.  {
  322.   for(register int j=0; j<4; j++)
  323.   {
  324.    tmp[i] = tmp[i] + (vec[j] * op2.mat[i][j]);
  325.   }
  326.  }
  327.  
  328.  op1 -> assign(tmp[0], tmp[1], tmp[2]);
  329. }
  330.  
  331. void multiply(vector *op1, matrix *op2)
  332. {
  333.  long tmp[3];
  334.  long vec[4];
  335.  
  336.  for(register int i=0; i<3; i++)  tmp[i] = 0;
  337.  
  338.  vec[0] = op1 -> get_x();
  339.  vec[1] = op1 -> get_y();
  340.  vec[2] = op1 -> get_z();
  341.  vec[3] = 1.0;
  342.  
  343.  // multiply vector with transformation matrix
  344.  for(i=0; i<3; i++)
  345.  {
  346.   for(register int j=0; j<4; j++)
  347.   {
  348.    tmp[i] = tmp[i] + (vec[j] * op2 -> mat[i][j]);
  349.   }
  350.  }
  351.  
  352.  op1 -> assign(tmp[0], tmp[1], tmp[2]);
  353. }
  354.  
  355.  
  356.  
  357.  
  358. matrix::~matrix(void)
  359. {
  360.  for(register int i=0; i<3; i++)
  361.   {
  362.    for(register int j=0; j<4; j++)   mat[i][j] = 0;
  363.   }
  364. }
  365.  
  366.  
  367.  
  368. class surface
  369. {
  370.  private:
  371.    int vertices;        // no. of vertices in the surface
  372.    int *vert_list;        // vertices list
  373.    boolean visible;        // is surface visible
  374.    int shaded_visible;
  375.    vector norm_vec;        // normal of the surface
  376.  public:
  377.    surface(void);
  378.    void init_vert(int no);
  379.    void set_vert(int mat[]);
  380.    int get_no_of_verts(void)    {return vertices;};
  381.    int get_vert(int pos)    {return vert_list[pos];};
  382.    boolean get_visible(void)    {return visible;};
  383.    int get_shading(void)    {return shaded_visible;};
  384.    void calculate_normal(vector *v_ptr);
  385.    void calculate_visibility(vector light_source);
  386.    void calculate_shading(vector light_source);
  387.    ~surface(void);
  388. };
  389.  
  390. surface::surface(void)
  391. {
  392.  vertices = 0;
  393.  visible = true;
  394.  shaded_visible = 0;
  395. }
  396.  
  397. void surface::init_vert(int no)
  398. {
  399.  vertices = no;
  400.  vert_list = new int[no];
  401.  if (!vert_list)
  402.  {
  403.   cout << "Allocation failure\n";
  404.  }
  405. }
  406.  
  407. void surface::set_vert(int mat[])
  408. {
  409.  for(register int i=0; i<vertices; i++)
  410.  {
  411.   vert_list[i] = mat[i];
  412.  }
  413. }
  414.  
  415. void surface::calculate_normal(vector *v_ptr)
  416. {
  417.  vector vec_1, vec_2;
  418.  int surf0, surf1, surf2;
  419.  
  420.  surf0 = vert_list[0];
  421.  surf1 = vert_list[1];
  422.  surf2 = vert_list[2];
  423.  vec_1 = v_ptr[surf1] - v_ptr[surf0];
  424.  vec_2 = v_ptr[surf2] - v_ptr[surf0];
  425.  norm_vec = normal(vec_1, vec_2);
  426. }
  427.  
  428. void surface::calculate_visibility(vector light_source)
  429. {
  430.  if (dotproduct(norm_vec,light_source) > 0) visible = true;
  431.   else visible = false;
  432. }
  433.  
  434. void surface::calculate_shading(vector light_source)
  435. {
  436.  float norm_x,x2,norm_y,y2,norm_z,z2;
  437.  double norm_factor, light_factor;
  438.  float intensity;
  439.  
  440.  norm_x = norm_vec.get_x();
  441.  norm_y = norm_vec.get_y();
  442.  norm_z = norm_vec.get_z();
  443.  x2 = light_source.get_x();
  444.  y2 = light_source.get_y();
  445.  z2 = light_source.get_z();
  446.  
  447.  norm_factor = 1/sqrt(((double) ((norm_x*norm_x)+(norm_y*norm_y)+(norm_z*norm_z))));
  448.  light_factor = 1/sqrt(((double) ((x2*x2)+(y2*y2)+(z2*z2))));
  449.  
  450.  norm_x *= norm_factor;
  451.  norm_y *= norm_factor;
  452.  norm_z *= norm_factor;
  453.  x2 *= light_factor;
  454.  y2 *= light_factor;
  455.  z2 *= light_factor;
  456.  
  457.  //intensity = (x1*x2)+(y1*y2)+(z1*z2);
  458.  intensity = (norm_x*x2)+(norm_y*y2)+(norm_z*z2);
  459.  
  460.  // find the shading intensity
  461.  intensity *= 15;   //15 shades of grey
  462.  
  463.  // is it visible ?
  464.  
  465.  if (intensity > 0)
  466.  {
  467.   shaded_visible = intensity;
  468.   visible = true;
  469.  }
  470.   else
  471.  {
  472.   visible = false;
  473.   shaded_visible = -1;
  474.  }
  475. }
  476.  
  477.  
  478. surface::~surface(void)
  479. {
  480.  delete vert_list;
  481. }
  482.  
  483.  
  484.  
  485.  
  486. // define global variables
  487.  
  488. int no_of_surfaces;
  489. int no_of_vertices;
  490.  
  491. const int origin_x = 319;
  492. const int origin_y = 240;
  493.  
  494.  
  495.  
  496.  
  497.